﻿#pragma once
#include "nlohmann/json.hpp"
#include <array>
#include <cstring>
#include <map>
#include <unordered_set>
#include <windows.h>

// data.hpp：用于存储和定义按键相关的类
namespace Clicker {
class KeyInfo {
  private:
    int vkeyID;
    std::wstring keyName;
    int type;

  public:
    enum Types { mouse = 0, keyboard = 1 };
    inline static std::map<int, std::wstring> keyMap;
    inline static std::map<int, std::vector<int>> mouseKey;

  public:
    KeyInfo() { modify_vkeyID(-1); }
    KeyInfo(int vkeyID) { modify_vkeyID(vkeyID); }
    int modify_vkeyID(int vkeyID) {
        this->vkeyID = vkeyID;
        auto get = keyMap.find(vkeyID);
        if (get != keyMap.end()) {
            this->keyName = get->second;
        } else {
            wchar_t *tmp = new wchar_t[30];
            wsprintf(tmp, L"%#x", vkeyID);
            this->keyName = tmp;
            delete[] tmp;
        }

        // 检查按键，只有这几个键是鼠标
        std::unordered_set<int> mouse_buttons = {1, 2, 4, 5, 6};
        if (mouse_buttons.count(vkeyID)) {
            this->type = mouse;
        } else {
            this->type = keyboard;
        }

        // 将鼠标的对应存储到数组中
        // 鼠标按键需要采用mouse_event()来调用，和虚拟键代码不一样，单独处理
        mouseKey[VK_LBUTTON] = {MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP};
        mouseKey[VK_RBUTTON] = {MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP};
        mouseKey[VK_MBUTTON] = {MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP};

        return 0;
    }

    std::vector<int> getMouseEvent() {
        if (this->type != mouse) {
            return {};
        } else {
            auto it = mouseKey.find(this->vkeyID);
            if (it != mouseKey.end()) {
                return it->second;
            } else {
                return {};
            }
        }
    }

    std::wstring getStr() const { return keyName; }

    int getID() const { return vkeyID; }

    int getType() const { return type; }

    // 加载keyMap
    static int init_keyMap() {
        keyMap[VK_LBUTTON] = L"鼠标左键";
        keyMap[VK_RBUTTON] = L"鼠标右键";
        keyMap[VK_CANCEL] = L"控制中断处理";
        keyMap[VK_MBUTTON] = L"鼠标中键";
        keyMap[VK_XBUTTON1] = L"鼠标X1键";
        keyMap[VK_XBUTTON2] = L"鼠标X2键";
        keyMap[VK_BACK] = L"退格";
        keyMap[VK_TAB] = L"Tab";
        keyMap[VK_CLEAR] = L"清除";
        keyMap[VK_RETURN] = L"回车";
        keyMap[VK_SHIFT] = L"Shift";
        keyMap[VK_CONTROL] = L"Ctrl";
        keyMap[VK_MENU] = L"Alt";
        keyMap[VK_PAUSE] = L"暂停";
        keyMap[VK_CAPITAL] = L"大写锁定";
        keyMap[VK_KANA] = L"IME假名模式";
        keyMap[VK_HANGUL] = L"IME韩文模式";
        keyMap[VK_IME_ON] = L"IME开";
        keyMap[VK_JUNJA] = L"IME准字模式";
        keyMap[VK_FINAL] = L"IME最终模式";
        keyMap[VK_HANJA] = L"IME韩文汉字模式";
        keyMap[VK_KANJI] = L"IME汉字模式";
        keyMap[VK_IME_OFF] = L"IME关";
        keyMap[VK_ESCAPE] = L"Esc";
        keyMap[VK_CONVERT] = L"IME转换";
        keyMap[VK_NONCONVERT] = L"IME不转换";
        keyMap[VK_ACCEPT] = L"IME接受";
        keyMap[VK_MODECHANGE] = L"IME模式更改请求";
        keyMap[VK_SPACE] = L"空格";
        keyMap[VK_PRIOR] = L"Page Up";
        keyMap[VK_NEXT] = L"Page Down";
        keyMap[VK_END] = L"End";
        keyMap[VK_HOME] = L"Home";
        keyMap[VK_LEFT] = L"左箭头";
        keyMap[VK_UP] = L"上箭头";
        keyMap[VK_RIGHT] = L"右箭头";
        keyMap[VK_DOWN] = L"下箭头";
        keyMap[VK_SELECT] = L"选择";
        keyMap[VK_PRINT] = L"打印";
        keyMap[VK_EXECUTE] = L"执行";
        keyMap[VK_SNAPSHOT] = L"打印屏幕";
        keyMap[VK_INSERT] = L"Insert";
        keyMap[VK_DELETE] = L"Delete";
        keyMap[VK_HELP] = L"帮助";
        keyMap[0x30] = L"0";
        keyMap[0x31] = L"1";
        keyMap[0x32] = L"2";
        keyMap[0x33] = L"3";
        keyMap[0x34] = L"4";
        keyMap[0x35] = L"5";
        keyMap[0x36] = L"6";
        keyMap[0x37] = L"7";
        keyMap[0x38] = L"8";
        keyMap[0x39] = L"9";
        keyMap[0x41] = L"A";
        keyMap[0x42] = L"B";
        keyMap[0x43] = L"C";
        keyMap[0x44] = L"D";
        keyMap[0x45] = L"E";
        keyMap[0x46] = L"F";
        keyMap[0x47] = L"G";
        keyMap[0x48] = L"H";
        keyMap[0x49] = L"I";
        keyMap[0x4A] = L"J";
        keyMap[0x4B] = L"K";
        keyMap[0x4C] = L"L";
        keyMap[0x4D] = L"M";
        keyMap[0x4E] = L"N";
        keyMap[0x4F] = L"O";
        keyMap[0x50] = L"P";
        keyMap[0x51] = L"Q";
        keyMap[0x52] = L"R";
        keyMap[0x53] = L"S";
        keyMap[0x54] = L"T";
        keyMap[0x55] = L"U";
        keyMap[0x56] = L"V";
        keyMap[0x57] = L"W";
        keyMap[0x58] = L"X";
        keyMap[0x59] = L"Y";
        keyMap[0x5A] = L"Z";
        keyMap[VK_LWIN] = L"左Windows徽标";
        keyMap[VK_RWIN] = L"右Windows徽标";
        keyMap[VK_APPS] = L"应用程序";
        keyMap[VK_SLEEP] = L"计算机睡眠";
        keyMap[VK_NUMPAD0] = L"小键盘0";
        keyMap[VK_NUMPAD1] = L"小键盘1";
        keyMap[VK_NUMPAD2] = L"小键盘2";
        keyMap[VK_NUMPAD3] = L"小键盘3";
        keyMap[VK_NUMPAD4] = L"小键盘4";
        keyMap[VK_NUMPAD5] = L"小键盘5";
        keyMap[VK_NUMPAD6] = L"小键盘6";
        keyMap[VK_NUMPAD7] = L"小键盘7";
        keyMap[VK_NUMPAD8] = L"小键盘8";
        keyMap[VK_NUMPAD9] = L"小键盘9";
        keyMap[VK_MULTIPLY] = L"乘号";
        keyMap[VK_ADD] = L"加号";
        keyMap[VK_SEPARATOR] = L"分隔符";
        keyMap[VK_SUBTRACT] = L"减号";
        keyMap[VK_DECIMAL] = L"小数点";
        keyMap[VK_DIVIDE] = L"除号";
        keyMap[VK_F1] = L"F1";
        keyMap[VK_F2] = L"F2";
        keyMap[VK_F3] = L"F3";
        keyMap[VK_F4] = L"F4";
        keyMap[VK_F5] = L"F5";
        keyMap[VK_F6] = L"F6";
        keyMap[VK_F7] = L"F7";
        keyMap[VK_F8] = L"F8";
        keyMap[VK_F9] = L"F9";
        keyMap[VK_F10] = L"F10";
        keyMap[VK_F11] = L"F11";
        keyMap[VK_F12] = L"F12";
        keyMap[VK_F13] = L"F13";
        keyMap[VK_F14] = L"F14";
        keyMap[VK_F15] = L"F15";
        keyMap[VK_F16] = L"F16";
        keyMap[VK_F17] = L"F17";
        keyMap[VK_F18] = L"F18";
        keyMap[VK_F19] = L"F19";
        keyMap[VK_F20] = L"F20";
        keyMap[VK_F21] = L"F21";
        keyMap[VK_F22] = L"F22";
        keyMap[VK_F23] = L"F23";
        keyMap[VK_F24] = L"F24";
        keyMap[VK_NUMLOCK] = L"数字锁定";
        keyMap[VK_SCROLL] = L"滚动锁定";
        keyMap[VK_LSHIFT] = L"左Shift";
        keyMap[VK_RSHIFT] = L"右Shift";
        keyMap[VK_LCONTROL] = L"左Ctrl";
        keyMap[VK_RCONTROL] = L"右Ctrl";
        keyMap[VK_LMENU] = L"左Alt";
        keyMap[VK_RMENU] = L"右Alt";
        keyMap[VK_BROWSER_BACK] = L"浏览器后退";
        keyMap[VK_BROWSER_FORWARD] = L"浏览器前进";
        keyMap[VK_BROWSER_REFRESH] = L"浏览器刷新";
        keyMap[VK_BROWSER_STOP] = L"浏览器停止";
        keyMap[VK_BROWSER_SEARCH] = L"浏览器搜索";
        keyMap[VK_BROWSER_FAVORITES] = L"浏览器收藏";
        keyMap[VK_BROWSER_HOME] = L"浏览器主页";
        keyMap[VK_VOLUME_MUTE] = L"音量静音";
        keyMap[VK_VOLUME_DOWN] = L"音量减小";
        keyMap[VK_VOLUME_UP] = L"音量增大";
        keyMap[VK_MEDIA_NEXT_TRACK] = L"下一曲目";
        keyMap[VK_MEDIA_PREV_TRACK] = L"上一曲目";
        keyMap[VK_MEDIA_STOP] = L"停止媒体";
        keyMap[VK_MEDIA_PLAY_PAUSE] = L"播放/暂停媒体";
        keyMap[VK_LAUNCH_MAIL] = L"启动邮件";
        keyMap[VK_LAUNCH_MEDIA_SELECT] = L"选择媒体";
        keyMap[VK_LAUNCH_APP1] = L"启动应用程序1";
        keyMap[VK_LAUNCH_APP2] = L"启动应用程序2";
        keyMap[VK_OEM_1] = L"分号和冒号";
        keyMap[VK_OEM_PLUS] = L"等号和加号";
        keyMap[VK_OEM_COMMA] = L"逗号和小于号";
        keyMap[VK_OEM_MINUS] = L"破折号和下划线";
        keyMap[VK_OEM_PERIOD] = L"句点和大于号";
        keyMap[VK_OEM_2] = L"正斜杠和问号";
        keyMap[VK_OEM_3] = L"重音符和波浪号";
        keyMap[VK_GAMEPAD_A] = L"游戏手柄A按钮";
        keyMap[VK_GAMEPAD_B] = L"游戏手柄B按钮";
        keyMap[VK_GAMEPAD_X] = L"游戏手柄X按钮";
        keyMap[VK_GAMEPAD_Y] = L"游戏手柄Y按钮";
        keyMap[VK_GAMEPAD_RIGHT_SHOULDER] = L"游戏手柄右肩按钮";
        keyMap[VK_GAMEPAD_LEFT_SHOULDER] = L"游戏手柄左肩按钮";
        keyMap[VK_GAMEPAD_LEFT_TRIGGER] = L"游戏手柄左扳机按钮";
        keyMap[VK_GAMEPAD_RIGHT_TRIGGER] = L"游戏手柄右扳机按钮";
        keyMap[VK_GAMEPAD_DPAD_UP] = L"游戏手柄方向上";
        keyMap[VK_GAMEPAD_DPAD_DOWN] = L"游戏手柄方向下";
        keyMap[VK_GAMEPAD_DPAD_LEFT] = L"游戏手柄方向左";
        keyMap[VK_GAMEPAD_DPAD_RIGHT] = L"游戏手柄方向右";
        keyMap[VK_GAMEPAD_MENU] = L"游戏手柄菜单/开始按钮";
        keyMap[VK_GAMEPAD_VIEW] = L"游戏手柄视图/返回按钮";
        keyMap[VK_GAMEPAD_LEFT_THUMBSTICK_BUTTON] = L"游戏手柄左摇杆按钮";
        keyMap[VK_GAMEPAD_RIGHT_THUMBSTICK_BUTTON] = L"游戏手柄右摇杆按钮";
        keyMap[VK_GAMEPAD_LEFT_THUMBSTICK_UP] = L"游戏手柄左摇杆上";
        keyMap[VK_GAMEPAD_LEFT_THUMBSTICK_DOWN] = L"游戏手柄左摇杆下";
        keyMap[VK_GAMEPAD_LEFT_THUMBSTICK_RIGHT] = L"游戏手柄左摇杆右";
        keyMap[VK_GAMEPAD_LEFT_THUMBSTICK_LEFT] = L"游戏手柄左摇杆左";
        keyMap[VK_GAMEPAD_RIGHT_THUMBSTICK_UP] = L"游戏手柄右摇杆上";
        keyMap[VK_GAMEPAD_RIGHT_THUMBSTICK_DOWN] = L"游戏手柄右摇杆下";
        keyMap[VK_GAMEPAD_RIGHT_THUMBSTICK_RIGHT] = L"游戏手柄右摇杆右";
        keyMap[VK_GAMEPAD_RIGHT_THUMBSTICK_LEFT] = L"游戏手柄右摇杆左";
        keyMap[VK_OEM_4] = L"左括号";
        keyMap[VK_OEM_5] = L"反斜杠和竖线";
        keyMap[VK_OEM_6] = L"右括号";
        keyMap[VK_OEM_7] = L"引号和双引号";
        keyMap[VK_OEM_8] = L"OEM特定";
        keyMap[VK_OEM_102] = L"反斜杠和竖线(ISO)";
        keyMap[VK_PROCESSKEY] = L"IME处理";
        keyMap[VK_PACKET] = L"Unicode字符输入";
        keyMap[VK_ATTN] = L"Attn";
        keyMap[VK_CRSEL] = L"CrSel";
        keyMap[VK_EXSEL] = L"ExSel";
        keyMap[VK_EREOF] = L"擦除EOF";
        keyMap[VK_PLAY] = L"播放";
        keyMap[VK_ZOOM] = L"缩放";
        keyMap[VK_PA1] = L"PA1";
        keyMap[VK_OEM_CLEAR] = L"清除";
        return 0;
    }
};

// 主窗口过程传输给线程
class ClickerConfig {
  public:
    Clicker::KeyInfo key;
    int iTimes;
    int iSleep;
    bool bMoveToPos;
    bool bLockMouse;
    bool show;
    POINT pos;

    ClickerConfig() {
        this->iSleep = 0;
        this->iTimes = 0;
        this->pos = { 0,0 };
        this->bMoveToPos = 0;
        this->bLockMouse = 0;
        this->show = 0;
    }
    ClickerConfig(bool show,int iTimes, int iSleep, Clicker::KeyInfo key) {
        ModifyConfig(show, iTimes, iSleep, key);
    }

    void ModifyConfig(bool show,int iTimes, int iSleep, Clicker::KeyInfo key) {
        this->show = show;
        this->key = key;
        this->iSleep = iSleep;
        this->iTimes = iTimes;
    }

    int SetPosConfig(bool bMoveToPos, bool bLockMouse, POINT pos) {
        if (key.getType() != KeyInfo::mouse) {
            return -1;
        } else {
            this->bMoveToPos = bMoveToPos;
            this->bLockMouse = bLockMouse;
            this->pos = pos;
        }
    }
};
} // namespace Clicker